package com.warmheart.base.config;

import javax.persistence.EntityManager;
import javax.sql.DataSource;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.warmheart.base.config.RsInterceptor;

@Configuration
@ConditionalOnClass({ EnableTransactionManagement.class, EntityManager.class })
@AutoConfigureAfter({ DataBaseConfiguration.class })
public class MybatisConfiguration implements EnvironmentAware {

    private static final Logger logger = LoggerFactory.getLogger(MybatisConfiguration.class);

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("dataSource") DataSource dataSource) throws Exception {
        long startTime = System.currentTimeMillis();
        SqlSessionTemplate sqlSession = null;
        try {
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(dataSource);
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            // 加载基础SQL
            Resource[] sqlsResources = resolver.getResources("classpath*:sqls/*/*/*.xml");
            // 加载自定义SQL
            Resource[] mapsResources = resolver.getResources("classpath*:maps/*/*/*.xml");
            // 合并SQL
            Resource[] resources = ArrayUtils.addAll(sqlsResources, mapsResources);
            // 设置SQL
            sessionFactory.setMapperLocations(resources);
            // 配置拦截器
            sessionFactory.setPlugins(new Interceptor[] { new RsInterceptor() });
            // 获取SqlSessionFactory
            SqlSessionFactory factory = sessionFactory.getObject();

            // 在取得的值为null时也调用 setter
            factory.getConfiguration().setCallSettersOnNulls(true);

            // 开启二级缓存，注意mapper.xml文件中需要使用cache标签来开启
            factory.getConfiguration().setCacheEnabled(true);

            // 禁用延迟加载
            factory.getConfiguration().setLazyLoadingEnabled(false);
            // 加载所有属性
            factory.getConfiguration().setAggressiveLazyLoading(true);
            // 驼峰映射
            factory.getConfiguration().setMapUnderscoreToCamelCase(true);

            sqlSession = new SqlSessionTemplate(factory);
        } catch (Exception ex) {
            logger.error("......configruing sqlsession is error......", ex);
        }
        logger.info("......configruing sqlsession end time is:{}ms......", (System.currentTimeMillis() - startTime));
        return sqlSession;
    }

    @Bean(name = "whTransactionManager")
    public DataSourceTransactionManager whTransactionManager(@Qualifier("dataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Override
    public void setEnvironment(Environment environment) {
    }
}
